package org.korifey.ffbdd.impl.op;

import org.korifey.ffbdd.api.IBddBackend;
import org.korifey.ffbdd.api.INode;
import org.korifey.ffbdd.api.op.IBinaryOperation;
import org.korifey.ffbdd.api.op.IOpCachePair;
import org.korifey.ffbdd.api.op.IOperation;
import org.korifey.ffbdd.api.op.OpCacheKey;
import org.korifey.ffbdd.api.op.OperationEnum;
import org.korifey.ffbdd.api.op.OpCacheKey.Binary;
import org.korifey.ffbdd.api.op.OpCacheKey.Unary;
import org.korifey.ffbdd.impl.BitvectorConst;
import org.korifey.ffbdd.impl.op.OpCacheKeyBitvector.BinaryBitvector;
import org.korifey.ffbdd.impl.op.OpCacheKeyBitvector.UnaryBitvector;

import static org.korifey.ffbdd.common.util.ByteUtil.*;

public class OpCachePairBitvector implements IOpCachePair {
	private OpCacheKey key;
	private INode value;
	
	@Override
	public OpCacheKey getKey() {		
		return key;
	}

	@Override
	public INode getValue() {
		return value;
	}
	
	
	
	public OpCachePairBitvector(OpCacheKey key, INode value) {
		super();
		this.key = key;
		this.value = value;
	}



	final static IOperation[] registeredOp;
	static {
		registeredOp = new IOperation[BitvectorConst.MAXOPS];
		for (OperationEnum en: OperationEnum.values()) {
			registeredOp[en.getOperation().code()] = en.getOperation();
		}
	}
	
	static void registerOperation(IOperation op) {
		registeredOp[op.code()] = op;
	}
		
	
	public static IOpCachePair parse(byte[] arr, int offset, IBddBackend backend) {
		int op = halfByteToInt(arr[offset+10], false);
		if (registeredOp[op] instanceof IBinaryOperation) {
			return BinaryBitvector.parse(arr, offset, backend);
		} else { //(registeredOp[op] instanceof Unop)
			return UnaryBitvector.parse(arr, offset, backend);
		}
	}

	public static void convertToBytes(OpCacheKey key, INode value, byte[] arr, int offset) {
		if (key instanceof Binary) {
			BinaryBitvector.convertToBytes((Binary)key, value, arr, offset);
		} else { //(key instanceof Unary) 
			UnaryBitvector.convertToBytes((Unary)key, value, arr, offset);
		}
		
	}
}
